package com.excell.support.excellbasic;

import cn.hutool.core.collection.CollectionUtil;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @User c.c
 * @Since 2022/12/6
 * @Time 14:48
 * @Description 基础元素(cell)
 */

@NoArgsConstructor
@Getter
public class ExcellCellBasics<T> {

  private ArrayList<ExcellCellBasics<T>> cellList = new ArrayList<>();
  private T vaule;
  private RowCell rowBasicCell;
  private ColumnCell columnCell;
  private HSSFCellStyle cellStyle;
  private Boolean isTitle;
  private String contentLocation;
  private HSSFCell hssfCell;


  public ExcellCellBasics(T vaule, RowCell rowBasicCell, ColumnCell columnCell) {
    this.vaule = vaule;
    this.rowBasicCell = rowBasicCell;
    this.columnCell = columnCell;
  }

  public ExcellCellBasics(T vaule,
                          @NonNull RowCell rowBasicCell,
                          @NonNull ColumnCell columnCell,
                          HSSFCellStyle cellStyle) {
    this.vaule = vaule;
    this.rowBasicCell = rowBasicCell;
    this.columnCell = columnCell;
    this.cellStyle = cellStyle;
  }


  public ExcellCellBasics(T vaule, RowCell rowBasicCell, ColumnCell columnCell, HSSFCellStyle cellStyle, Boolean isTitle, String contentLocation, HSSFCell hssfCell) {
    this.vaule = vaule;
    this.rowBasicCell = rowBasicCell;
    this.columnCell = columnCell;
    this.cellStyle = cellStyle;
    this.isTitle = isTitle;
    this.contentLocation = contentLocation;
    this.hssfCell = hssfCell;
  }

  public ExcellCellBasics(T vaule,
                          @NonNull RowCell rowBasicCell,
                          @NonNull ColumnCell columnCell,
                          HSSFCellStyle cellStyle,
                          Boolean isTitle) {
    this.vaule = vaule;
    this.rowBasicCell = rowBasicCell;
    this.columnCell = columnCell;
    this.cellStyle = cellStyle;
    this.isTitle = isTitle;
  }

  public ExcellCellBasics(T vaule, RowCell rowBasicCell, ColumnCell columnCell, HSSFCellStyle cellStyle, Boolean isTitle, String contentLocation) {
    this.vaule = vaule;
    this.rowBasicCell = rowBasicCell;
    this.columnCell = columnCell;
    this.cellStyle = cellStyle;
    this.isTitle = isTitle;
    this.contentLocation = contentLocation;
  }


  public ExcellCellBasics(HSSFCellStyle cellStyle) {
    this.cellStyle = cellStyle;
  }

  public void setVaule(T vaule) {
    this.vaule = vaule;
  }

  public void setCellStyle(HSSFCellStyle cellStyle) {
    this.cellStyle = cellStyle;
  }

  public void setHssfCell(HSSFCell hssfCell) {
    this.hssfCell = hssfCell;
  }

  /**
   * 获取基础样式
   *
   * @author C.c
   * @since 2022-12-27 16:18
   **/
  public HSSFCell getHssfCell() {
    return hssfCell;
  }

  /**
   * 获取下标位置
   *
   * @author C.c
   * @since 2022-12-23 14:45
   **/
  public String getContentLocation() {
    return contentLocation;
  }

  /**
   * 获取单元格
   *
   * @param contentLocation 行:列
   * @return ExcellCellBasics<T>
   * @author C.c
   * @since 2022-12-23 14:53
   **/
  public ExcellCellBasics<T> getCell(String contentLocation) {
    String[] split = contentLocation.split(":");
    ArrayList<ExcellCellBasics<T>> cellList = this.cellList;
    return cellList
      .stream()
      .filter(excellCellBasics ->
        excellCellBasics.getRowBasicCell().getStart().equals(Integer.parseInt(split[0]) - 1) &&
          excellCellBasics.getRowBasicCell().getStart().equals(Integer.parseInt(split[1]) - 1))
      .findAny().orElse(null);
  }

  public ExcellCellBasics<T> getCell(int row, int column) {
    ArrayList<ExcellCellBasics<T>> cellList = this.cellList;
    ExcellCellBasics<T> excellCellBasics1 = cellList
      .stream()
      .filter(excellCellBasics ->
        excellCellBasics.getRowBasicCell().getStart().equals(row - 1) &&
          excellCellBasics.getColumnCell().getStart().equals(column - 1))
      .findAny().orElse(null);
    return excellCellBasics1;
  }

  public void delete(int row, int column) {
    ExcellCellBasics<T> cell = this.getCell(row, column);
    cellList.remove(cell);
  }

  public void delete(ExcellCellBasics<T> excellCellBasics) {
    cellList.indexOf(excellCellBasics);
    this.cellList.remove(excellCellBasics);
  }

  public void delete(String contentLocation) {
    ExcellCellBasics<T> cell = this.getCell(contentLocation);

    this.cellList.remove(cell);
  }

  public void add(ExcellCellBasics<T> excellCellBasics) {
    this.cellList.add(excellCellBasics);
  }

  /**
   * @param basicCellStyle 全局默认样式
   * @return
   * @author C.c
   * @since 2022-12-21 15:49
   **/
  public static <T> ExcellCellBasics<T> getInstance(HSSFCellStyle basicCellStyle) {
    return new ExcellCellBasics<>(basicCellStyle);
  }

  public static <T> ExcellCellBasics<T> getInstance() {
    return new ExcellCellBasics<>();
  }


  public ExcellCellBasics<T> initTitle(T vaule, RowCell rowBasicCell, ColumnCell columnCell) {
    return this.initTitle(vaule, rowBasicCell, columnCell, cellStyle, null);
  }


  public ExcellCellBasics<T> initTitle(T vaule, RowCell rowBasicCell, ColumnCell columnCell, HSSFCellStyle hssfCellStyle) {

    return this.initTitle(vaule, rowBasicCell, columnCell, hssfCellStyle, null);
  }

  public ExcellCellBasics<T> initTitle(T vaule, RowCell rowBasicCell, ColumnCell columnCell, HSSFCellStyle hssfCellStyle, HSSFCell hssfCell) {

    ExcellCellBasics<T> excellCellBasics = new ExcellCellBasics<>(vaule, rowBasicCell, columnCell, hssfCellStyle, true, rowBasicCell.getStart() + ":" + columnCell.getStart(), hssfCell);
    cellList.add(excellCellBasics);
    return this;
  }


  public ExcellCellBasics<T> initContent(T vaule, int row, int column) {
    return this.initContent(vaule, RowCell.intiRow(row), ColumnCell.intiColumn(column), cellStyle);
  }

  public ExcellCellBasics<T> initContent(T vaule, int row, int column, HSSFCellStyle hssfCellStyle) {
    return this.initContent(vaule, RowCell.intiRow(row), ColumnCell.intiColumn(column), hssfCellStyle);
  }

  public ExcellCellBasics<T> initContent(T vaule, RowCell rowBasicCell, ColumnCell columnCell) {
    return this.initContent(vaule, rowBasicCell, columnCell, null);
  }

  public ExcellCellBasics<T> initContent(T vaule, RowCell rowBasicCell, ColumnCell columnCell, HSSFCellStyle hssfCellStyle) {
    ExcellCellBasics<T> excellCellBasics = new ExcellCellBasics<>(vaule, rowBasicCell, columnCell, hssfCellStyle);
    cellList.add(excellCellBasics);
    return this;
  }

  public List<ExcellCellBasics<T>> getCellList() {
    return cellList;
  }


  /**
   * 获取表格当前有多少行
   *
   * @return Integer
   * @author C.c
   * @since 2022-12-21 11:46
   **/
  public Integer getMaxRowSize() {
    if (CollectionUtil.isEmpty(this.getCellList())) {
      return 0;
    }
    int maxRow = 0;
    for (ExcellCellBasics<T> tExcellCellBasics : this.getCellList()) {
      maxRow = tExcellCellBasics.getRowBasicCell().getEnd() > maxRow ? tExcellCellBasics.getRowBasicCell().getEnd() : maxRow;
    }
    return maxRow + 1;
  }

  /**
   * 获取表格当前有多少列
   *
   * @return Integer
   * @author C.c
   * @since 2022-12-21 11:46
   **/
  public Integer getMaxColumnSize() {
    if (CollectionUtil.isEmpty(this.getCellList())) {
      return 0;
    }
    int maxColumn = 0;
    for (ExcellCellBasics<T> tExcellCellBasics : this.getCellList()) {
      maxColumn = tExcellCellBasics.getColumnCell().getEnd() > maxColumn ? tExcellCellBasics.getColumnCell().getEnd() : maxColumn;
    }
    return maxColumn + 1;
  }


  /**
   * 获取某行，每一列的内容
   *
   * @param indexRow 哪一行
   * @author C.c
   * @since 2022-12-21 11:47
   **/
  public List<T> getContent(Integer indexRow) {
    List<ExcellCellBasics<T>> cellList = this.getCellList();

    //获取这一行的列
    return cellList.stream()
      //根据某一行过滤
      .filter(excellCellBasics -> excellCellBasics.getRowBasicCell().getEnd().equals(indexRow))
      //按列从小到大排序（无所谓end还是start）
      .sorted(Comparator.comparing(excellCellBasics -> excellCellBasics.getColumnCell().getEnd()))
      //过滤内容
      .map(ExcellCellBasics::getVaule).collect(Collectors.toList());
  }
}
